/*********************************************************************************************************************
 * COPYRIGHT NOTICE
 * Copyright (c) 2017,????
 * All rights reserved.
 * ????QQ?:179029047
 *
 * ????????????????,????????????,
 * ????????????,???????????????????
 *
 * @brief      		???(?????)??
 * @company	   		??????????
 * @author     		Go For It(1325536866)
 * @version    		v1.0
 * @Software 		MDK 5.17
 * @Target core		STM32F407ZGT6
 * @Taobao   		https://seekfree.taobao.com/
 * @date       		2017-10-11
 * @note
					????:
					------------------------------------
					????            ?????
					SDA                 A2
					SCL                 A3
					???              B7
					???              A4
					????            A6

					D0                  C6
					D1                  C7
					D2                  C8
					D3                  C9
					D4                  C11
					D5                  B6
					D6                  E5
					D7                  E6

					------------------------------------
                    USB?TTL????
					USB?TTL??        ?????
					TX                  A10
					RX                  A9

					?????              ??SEEKFREE_MT9V032.h ??????? COL ROW
					??FPS                 50?
 ********************************************************************************************************************/

#include "SEEKFREE_MT9V032.h"

#include "delay.h"

uint8_t *camera_buffer_addr;

uint8_t mt9v03x_image[MT9V03X_UART_H][MT9V03X_UART_W];      //????


uint8_t mt9v03x_uart_receive[3];
uint8_t mt9v03x_receive_num = 0;
volatile uint8_t mt9v03x_uart_receive_flag = 0;
uint8_t mt9v03x_rx_buff;

//???????????
int16_t MT9V03X_CFG[MT9V03X_CONFIG_FINISH][2]=
{
    {MT9V03X_AUTO_EXP,          0},   //??????      ??1-63 0??? ????????  EXP_TIME?????????????????,????????????
    //??????????????,???????????????,??????????????????????,???????
    {MT9V03X_EXP_TIME,          500}, //????          ??????????????????,????????????????????
    {MT9V03X_FPS,                50},  //????          ??????????????FPS,???????????????FPS
    {MT9V03X_SET_COL,           MT9V03X_UART_W}, //?????        ??1-752     K60???????188
    {MT9V03X_SET_ROW,           MT9V03X_UART_H}, //?????        ??1-480
    {MT9V03X_LR_OFFSET,         0},   //???????    ?? ???   ?? ???  ??188 376 752???????    ??????????????????,????????????????
    {MT9V03X_UD_OFFSET,         0},   //???????    ?? ???   ?? ???  ??120 240 480???????    ??????????????????,????????????????
    {MT9V03X_GAIN,              32},  //????          ??16-64     ???????????????????????


    {MT9V03X_INIT,              0}    //????????
};

//??????????????
int16_t MT9V03X_GET_CFG[MT9V03X_CONFIG_FINISH-1][2]=
{
    {MT9V03X_AUTO_EXP,          0},   //??????
    {MT9V03X_EXP_TIME,          0},   //????
    {MT9V03X_FPS,               0},   //????
    {MT9V03X_SET_COL,           0},   //?????
    {MT9V03X_SET_ROW,           0},   //?????
    {MT9V03X_LR_OFFSET,         0},   //???????
    {MT9V03X_UD_OFFSET,         0},   //???????
    {MT9V03X_GAIN,              0},   //????
};


//-------------------------------------------------------------------------------------------------------------------
//  @brief      ????8???
//  @param      USARTx			???
//  @param      Data			8???
//  @return     void
//  @since      v1.0
//  Sample usage:				?????????????
//-------------------------------------------------------------------------------------------------------------------
void put_char(USART_TypeDef* USARTx, uint8_t Data)
{
    while((USARTx->SR & 0X40)==0);
    USARTx->DR = Data;
}


void uart_putbuff(USART_TypeDef* USARTx, uint8_t *Data, uint16_t len)
{
    while(len--)
        put_char(USARTx, *Data++);
}


//-------------------------------------------------------------------------------------------------------------------
//  @brief      ??2???
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:					
//-------------------------------------------------------------------------------------------------------------------
//void uart2_init(uint32_t bound)
//{
//    GPIO_InitTypeDef GPIO_InitStructure;
//    USART_InitTypeDef USART_InitStructure;
//    NVIC_InitTypeDef NVIC_InitStructure;

//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//??GPIOA??
//    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);	//??USART2??

//    
//    //UART2_TX_A2   GPIOA.9
//    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//??????
//    GPIO_Init(GPIOA, &GPIO_InitStructure);//???GPIOA.9

//    //UART2_RX_A3	  GPIOA.10???
//    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//????
//    GPIO_Init(GPIOA, &GPIO_InitStructure);//???GPIOA.10  

//    //Usart2 NVIC ??
//    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//?????3
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//????3
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ????
//    NVIC_Init(&NVIC_InitStructure);	//??????????VIC???

//    //USART ?????

//    USART_InitStructure.USART_BaudRate = bound;//?????
//    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//???8?????
//    USART_InitStructure.USART_StopBits = USART_StopBits_1;//?????
//    USART_InitStructure.USART_Parity = USART_Parity_No;//??????
//    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//????????
//    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//????

//    USART_Init(USART2, &USART_InitStructure); //?????1
//    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//????????
//    USART_Cmd(USART2, ENABLE);                    //????1 
//}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ????????????????
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void mt9v03x_uart_tim1_etr_init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //????

	//PA12 PCLK
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;				 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; 	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
	
    TIM_Cmd(TIM1,DISABLE);
	TIM_TimeBaseStructure.TIM_Period = 0XFFFF; //???????????????????????????	 ???5000?500ms
	TIM_TimeBaseStructure.TIM_Prescaler =0; //??????TIMx???????????  10Khz?????  
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //??????:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM??????
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //??TIM_TimeBaseInitStruct?????????TIMx???????
    
    TIM_ETRClockMode1Config(TIM1, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);
    TIM_SelectInputTrigger(TIM1, TIM_TS_ETRF);
    TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);                   //TIM???:???????????????????????????
    TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);      //??????????
    
 
    TIM_DMACmd(TIM1, TIM_DMA_Trigger, ENABLE);                        //??TIM_DMA
}
 
//-------------------------------------------------------------------------------------------------------------------
//  @brief      ??????DMA???
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void mt9v03x_uart_dma_init(void)
{
	
	
    DMA_InitTypeDef DMA_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;
	  NVIC_InitTypeDef NVIC_InitStructure;
	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE);
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
	//8????????
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//??GPIOD??
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//????
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100M
    GPIO_Init(GPIOB, &GPIO_InitStructure);//???GPIOD

	
	/* ?? DMA  */
 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	
	DMA_DeInit(DMA1_Channel4);
	
   
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&GPIOB->IDR;       		//????
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)camera_buffer_addr;      			//????
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;              		//??????      	
    DMA_InitStructure.DMA_BufferSize = MT9V03X_UART_DMA_NUM;           				//BUFF??

    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  		//???????
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;           		//???????
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;	//??????:32?
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;   		//??????? 
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                   		// ?????? 
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;             	//????
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                			//??????
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);							//???DMA Stream
	
	/* DMA????  */
	DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);							//DMA??????
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;				//?????????????
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;				//?????0 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;						//????0 
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;							//????????
	NVIC_Init(&NVIC_InitStructure);  	  									//??NVIC_InitStruct???????????NVIC???


}


//-------------------------------------------------------------------------------------------------------------------
//  @brief      ????????????
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void mt9v03x_uart_vsync_init(void)
{   
	EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; 	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
	GPIO_Init(GPIOA, &GPIO_InitStructure);					
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);	//PB0????0 ??????
 	   	 
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  	//?????
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);								//??EXTI_InitStruct???????????EXTI???
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//?????????????
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	//?????0 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;			//????0 
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//????????
	NVIC_Init(&NVIC_InitStructure);  	  						//??NVIC_InitStruct???????????NVIC???
}





//-------------------------------------------------------------------------------------------------------------------
//  @brief      MT9V032?????????
//  @param      NULL
//  @return     void					
//  @since      v1.0
//  Sample usage:	
//  @note       ????ISR?? ??3???????
//-------------------------------------------------------------------------------------------------------------------
void mt9v032_cof_uart_interrupt(void)
{
    mt9v03x_uart_receive[mt9v03x_receive_num] = USART_ReceiveData(MT9V032_COF_UART);
    mt9v03x_receive_num++;
    
    if(1==mt9v03x_receive_num && 0XA5!=mt9v03x_uart_receive[0])  mt9v03x_receive_num = 0;
    if(3 == mt9v03x_receive_num)
    {
        mt9v03x_receive_num = 0;
        mt9v03x_uart_receive_flag = 1;
    }
        
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ???????????
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:				???????????uart2
//-------------------------------------------------------------------------------------------------------------------
void mt9v03x_get_all_config(USART_TypeDef* uartn, int16_t buff[MT9V03X_CONFIG_FINISH-1][2])
{
    uint16_t temp, i;
    uint8_t  send_buffer[4];

    for(i=0; i<MT9V03X_CONFIG_FINISH-1; i++)
    {
        send_buffer[0] = 0xA5;
        send_buffer[1] = MT9V03X_GET_STATUS;
        temp = buff[i][0];
        send_buffer[2] = temp>>8;
        send_buffer[3] = (uint8_t)temp;


        uart_putbuff(uartn, send_buffer,4);

        delay_ms(10);
        //????????
        while(!mt9v03x_uart_receive_flag)	delay_ms(1);


        mt9v03x_uart_receive_flag = 0;

        buff[i][1] = mt9v03x_uart_receive[1]<<8 | mt9v03x_uart_receive[2];

    }
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ?????????
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:				?????????????
//-------------------------------------------------------------------------------------------------------------------
uint16_t get_version(USART_TypeDef* uartn)
{
    uint16_t temp;
    uint8_t  send_buffer[4];
    send_buffer[0] = 0xA5;
    send_buffer[1] = MT9V03X_GET_STATUS;
    temp = MT9V03X_GET_VERSION;
    send_buffer[2] = temp>>8;
    send_buffer[3] = (uint8_t)temp;

    uart_putbuff(uartn, send_buffer,4);

    //????????
    while(!mt9v03x_uart_receive_flag);

    mt9v03x_uart_receive_flag = 0;

    return ((uint16_t)(mt9v03x_uart_receive[1]<<8) | mt9v03x_uart_receive[2]);
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ???????????
//  @param      light   ????????????,?????????????FPS?????????????????,??????????????
//  @return     uint16_t  ?????,??????????
//  @since      v1.0
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
uint16_t set_exposure_time(USART_TypeDef* uartn,uint16_t light)
{
    uint16_t temp;
    uint8_t  send_buffer[4];

    send_buffer[0] = 0xA5;
    send_buffer[1] = MT9V03X_SET_EXP_TIME;
    temp = light;
    send_buffer[2] = temp>>8;
    send_buffer[3] = (uint8_t)temp;

    uart_putbuff(uartn, send_buffer,4);

    //????????
    while(!mt9v03x_uart_receive_flag);

    mt9v03x_uart_receive_flag = 0;

    temp = mt9v03x_uart_receive[1]<<8 | mt9v03x_uart_receive[2];
    return temp;

}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ??????????????
//  @param      addr    ??????????
//  @param      data    ???????
//  @return     uint16_t  ???????,??????????
//  @since      v1.0
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
uint16_t set_mt9v032_reg(USART_TypeDef* uartn,uint8_t addr, uint16_t data)
{
    uint16_t temp;
    uint8_t  send_buffer[4];

    send_buffer[0] = 0xA5;
    send_buffer[1] = MT9V03X_SET_ADDR;
    temp = addr;
    send_buffer[2] = temp>>8;
    send_buffer[3] = (uint8_t)temp;

    uart_putbuff(uartn, send_buffer,4);
    delay_ms(10);

    send_buffer[0] = 0xA5;
    send_buffer[1] = MT9V03X_SET_DATA;
    temp = data;
    send_buffer[2] = temp>>8;
    send_buffer[3] = (uint8_t)temp;

    uart_putbuff(uartn, send_buffer,4);

    //????????
    while(!mt9v03x_uart_receive_flag);

    mt9v03x_uart_receive_flag = 0;

    temp = mt9v03x_uart_receive[1]<<8 | mt9v03x_uart_receive[2];

    return temp;

}
//-------------------------------------------------------------------------------------------------------------------
//  @brief      ?????????????????
//  @param      uartn   ??????????
//  @param      buff    ???????
//  @return     void
//  @since      v1.0
//  Sample usage:       ?????????????
//-------------------------------------------------------------------------------------------------------------------
void mt9v03x_set_all_config(USART_TypeDef* uartn, int16_t buff[MT9V03X_CONFIG_FINISH-1][2])
{
    uint16_t temp, i;
    uint8_t  send_buffer[4];

    mt9v03x_uart_receive_flag = 0;

    for(i=0; i<MT9V03X_CONFIG_FINISH; i++)
    {
        send_buffer[0] = 0xA5;
        send_buffer[1] = buff[i][0];
        temp           = buff[i][1];
        send_buffer[2] = temp>>8;
        send_buffer[3] = (uint8_t)temp;

        uart_putbuff(uartn, send_buffer, 4);
        delay_ms(10);
    }


    while(!mt9v03x_uart_receive_flag);
    mt9v03x_uart_receive_flag = 0;
    while((0xff !=  mt9v03x_uart_receive[1]) || (0xff !=  mt9v03x_uart_receive[2]))delay_ms(1);

}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ????????
//  @return     uint8       ?????
//  @since      v1.0
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
uint8_t mt9v03x_uart_init(void)
{
    camera_buffer_addr = mt9v03x_image[0];
    
    uart2_init(9600);
    
    //
    mt9v03x_uart_receive_flag = 0;
    mt9v03x_set_all_config(MT9V03X_UART_COF_UART, MT9V03X_CFG);
    // 
    mt9v03x_uart_receive_flag = 0;
    mt9v03x_get_all_config(MT9V03X_UART_COF_UART, MT9V03X_GET_CFG);

    //DMA
    mt9v03x_uart_dma_init();
    //GPIO????????,PLCK?????
    mt9v03x_uart_tim1_etr_init();
    //VSYNC
    mt9v03x_uart_vsync_init();

    return 0;
}


volatile uint8_t mt9v03x_uart_finish_flag = 0;
    
//-------------------------------------------------------------------------------------------------------------------
//  @brief      ?????????
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:                   ?isr.c????????????,???????(????????????)
//-------------------------------------------------------------------------------------------------------------------
void mt9v03x_uart_vsync(void)
{
    if(mt9v03x_uart_finish_flag == 0)                              /*?????,???*/
    {
        MT9V03X_UART_DMA_CH->CNDTR = MT9V03X_UART_DMA_NUM;             //????DMA???????,????,???????DMA???????
        MT9V03X_UART_DMA_CH->CCR |= DAC_CR_EN1;                    //??DMA1
        TIM1->DIER |= TIM_DMA_Trigger;                            //??TIM_DMA
    }
}

volatile uint8_t ov7725_uart_finish_flag = 0;
//-------------------------------------------------------------------------------------------------------------------
//  @brief      ??????DMA????
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:                   ?isr.c????????????,???????(????????????)
//-------------------------------------------------------------------------------------------------------------------
void mt9v03x_uart_dma(void)
{
    mt9v03x_uart_finish_flag = 1;                             //????????1
    MT9V03X_UART_DMA_CH->CCR &= (uint16_t)(~DAC_CR_EN1);      //??DMA1
    TIM1->DIER &= (uint16_t)~TIM_DMA_Trigger;                //??TIM_DMA
}


//-------------------------------------------------------------------------------------------------------------------
//  @brief      ????????
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:				???PB0 ,?????
//-------------------------------------------------------------------------------------------------------------------
void EXTI0_IRQHandler(void)
{
	if(SET == EXTI_GetITStatus(EXTI_Line0))
    {
		mt9v03x_uart_vsync();
    }
    EXTI_ClearITPendingBit(EXTI_Line0);//??LINE8???????  
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      DMA??????
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:					
//-------------------------------------------------------------------------------------------------------------------
void DMA1_Channel4_IRQHandler(void) 
{    
    if(SET == DMA_GetFlagStatus(DMA1_FLAG_TC4))
    {
        DMA_ClearFlag(DMA1_FLAG_TC4);
        mt9v03x_uart_dma();
    }
	
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ??2??????
//  @param      NULL
//  @return     void
//  @since      v1.0
//  Sample usage:					
//-------------------------------------------------------------------------------------------------------------------
//void USART2_IRQHandler(void)
//{
//	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //????(?????????0x0d 0x0a??)
//	{
//		mt9v032_cof_uart_interrupt();
//    }
//} 

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ?????????????????????
//  @param      *imgaddr            ????????
//  @param      *imgsize            ????(????OV7725_UART_SIZE)
//  @return     void
//  @since      v1.0
//  Sample usage:                   ?????????????
//-------------------------------------------------------------------------------------------------------------------
void seekfree_sendimg_mt9v03x(USART_TypeDef* uartn, void *imgaddr, uint32_t imgsize)
{
    uint32_t i;
    put_char(uartn,0x00);
    put_char(uartn,0xff);
    put_char(uartn,0x01);
    put_char(uartn,0x01);
    for(i=0; i<(imgsize); i++)
    {
        put_char(uartn,((uint8_t*)(imgaddr))[i]);
    }
}

